home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 201-225 / 214 / mandelvroom / src / mand.c < prev    next >
C/C++ Source or Header  |  1995-03-13  |  19KB  |  831 lines

  1. /*
  2.  * MandelVroom 2.0
  3.  *
  4.  * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
  5.  *
  6.  * All rights reserved.
  7.  *
  8.  * Permission is hereby granted to distribute this program's source
  9.  * executable, and documentation for non-comercial purposes, so long as the
  10.  * copyright notices are not removed from the sources, executable or
  11.  * documentation.  This program may not be distributed for a profit without
  12.  * the express written consent of the author Kevin L. Clague.
  13.  *
  14.  * This program is not in the public domain.
  15.  *
  16.  * Fred Fish is expressly granted permission to distribute this program's
  17.  * source and executable as part of the "Fred Fish freely redistributable
  18.  * Amiga software library."
  19.  *
  20.  * Permission is expressly granted for this program and it's source to be
  21.  * distributed as part of the Amicus Amiga software disks, and the
  22.  * First Amiga User Group's Hot Mix disks.
  23.  *
  24.  * contents: this file contains funtions to create, maintain and delete
  25.  * Mandelbrot and Julia projects (including spawning off child generator
  26.  * tasks.)
  27.  */
  28.  
  29. #include "mandp.h"
  30.  
  31. struct NewWindow NewMand = {
  32.    0,12,                     /* start position           */
  33.    80,80,                    /* width, height            */
  34.  
  35.    (UBYTE) 0, (UBYTE) NORMALPEN,
  36.    NULL,                     /* IDCMP flags */
  37.    /* MandWind flags */
  38.    WINDOWCLOSE | WINDOWDEPTH | WINDOWSIZING | WINDOWDRAG | ACTIVATE |
  39.    REPORTMOUSE | NOCAREREFRESH | SMART_REFRESH,
  40.    (struct Gadget *) NULL,   /* first gadget             */
  41.    (struct Image *) NULL,    /* user checkmark           */
  42.    (UBYTE *) NULL,           /* Title                    */
  43.    (struct Screen *) NULL,   /* pointer to screen        */
  44.    (struct BitMap *) NULL,   /* pointer to superbitmap   */
  45.    20,20,-1,-1,              /* sizing                   */
  46.    CUSTOMSCREEN              /* type of screen           */
  47.    };
  48.  
  49. LONG TopMarg   = 10;
  50. LONG BotMarg   =  2;
  51. LONG LeftMarg  =  2;
  52. LONG RightMarg;
  53.  
  54. ULONG CalcTime;
  55.  
  56. extern LONG TaskPri, MainPri;
  57. extern LONG pSigMask;
  58.  
  59. extern struct ExecBase *ExecBase;
  60.  
  61. static struct Picture *GenNPict;
  62.  
  63. /* Toggle generation of project */
  64.  
  65. GenerateCmd(Msg)
  66.   struct IntuiMessage *Msg;
  67. {
  68.   switch(Msg->Class) {
  69.  
  70.     case GADGETDOWN:
  71.          ToggleGen((struct Picture *) Msg->IDCMPWindow->UserData);
  72.          break;
  73.  
  74.     case MENUPICK:
  75.          switch( SUBNUM(Msg->Code) ) {
  76.            case STARTGEN:
  77.  
  78.              CurPict->GenState = GENPENDSTATE;
  79.              Generate( CurPict );
  80.              break;
  81.  
  82.            case STOPGEN:
  83.  
  84.              ThrowTask(CurPict);
  85.              break;
  86.  
  87.            case CONTGEN:
  88.  
  89.              CurPict->GenState = CONTINUESTATE;
  90.              Generate( CurPict );
  91.              break;
  92.          }
  93.          break;
  94.   }
  95. }
  96.  
  97. ToggleGen( Pict )
  98.   struct Picture *Pict;
  99. {
  100.   if ( Pict->gTask ) {
  101.  
  102.     ThrowTask( Pict );
  103.   } else {
  104.  
  105.     Pict->GenState = GENPENDSTATE;
  106.     Generate( Pict );
  107.   }
  108.   SetGenGad( Pict );
  109. }
  110.  
  111. /*
  112.  * Generate It
  113.  */
  114. Generate( Pict )
  115.   register struct Picture *Pict;
  116. {
  117.  
  118.   register char *t;
  119.  
  120.   int GenTask();
  121.  
  122.   extern struct MenuItem LensSub[];
  123.  
  124.   if ( Pict->gTask ) {
  125.     return;
  126.   }
  127.  
  128.   if (Pict->Flags & SCROLL_HAPPENED) {
  129.  
  130.     /* create a new counts array with unclipped data in it */
  131.     /* adjust the real and imaginary upper left */
  132.  
  133.     ScrollComplex(Pict);
  134.  
  135.     if (Pict->Counts == NULL)
  136.       return;
  137.  
  138.   } else {
  139.  
  140.     FreeScrollTemp(Pict);
  141.  
  142.     if (Pict->GenState == CONTINUESTATE ){
  143.       if ( Pict->CurLine < Pict->CountY ) {
  144.         if (Pict->Counts == NULL) return;
  145.       } else {
  146.         return;
  147.       }
  148.     }
  149.  
  150.     if (Pict->GenState == GENPENDSTATE) {
  151.  
  152.       InitNewGen( Pict );
  153.       if (Pict->Counts == NULL) return;
  154.     }
  155.   }
  156.   ResetScrollRects(Pict);
  157.  
  158.   Pict->GenState = GENERATESTATE;
  159.  
  160.   if ( Pict->MathMode == INTIIGENERATOR &&
  161.       (ExecBase->AttnFlags & (1 << AFB_68020)) == 0 ) {
  162.  
  163.     Pict->MathMode = INTGENERATOR;
  164.   }
  165.  
  166.   if ( Pict->MathMode == _81GENERATOR &&
  167.        (ExecBase->AttnFlags & (1 << AFB_68881)) == 0 ) {
  168.  
  169.     Pict->MathMode = IEEEGENERATOR;
  170.   }
  171.  
  172.   MakeColorXlate( Pict );
  173.  
  174.   if (Pict->MathMode == 1) {
  175.  
  176.     if (OpenFFPLibs() != 0)
  177.       return;
  178.   }
  179.  
  180.   /* Spawn off the generator as a task */
  181.  
  182.   DateStamp( Pict->TimeStamp );
  183.  
  184.   /* GenNPict is pointer to Picture that task needs to generate */
  185.  
  186.   GenNPict = Pict;
  187.  
  188. #define KAY (1024L)
  189.  
  190. #ifdef MULTI
  191.   Pict->gTask = CreateTask( Pict->Title+2, MainPri, GenTask, KAY);
  192.  
  193.   if ( Pict->gTask == NULL ) {
  194.     DispErrMsg("Could not create task",0);
  195.   }
  196.  
  197.   SetGenGad( Pict );
  198.  
  199.   /* Do this so we are sure child is done with GenNPict */
  200.  
  201.   Wait( pSigMask );
  202.  
  203. #else
  204.   GenTask();
  205. #endif
  206. }
  207.  
  208. InitNewGen( Pict )
  209.   register struct Picture *Pict;
  210. {
  211.  
  212.   if (Pict->Flags & BORDERLESS_PROJ) {
  213.  
  214.     Pict->LeftMarg  = 0;
  215.     Pict->RightMarg = 0;
  216.     Pict->TopMarg   = 0;
  217.     Pict->BotMarg   = 0;
  218.   }
  219.  
  220.   /* figure out new picture size */
  221.  
  222.   Pict->CountX = Pict->Window->Width-(Pict->LeftMarg+Pict->RightMarg);
  223.   Pict->CountY = Pict->Window->Height-(Pict->TopMarg+Pict->BotMarg);
  224.  
  225.   /* free up old counts memory, get new picture size, get new counts memory
  226.    */
  227.  
  228.   GetCountsMemory( Pict );
  229.  
  230.   if (Pict->Counts == NULL) {
  231.     DispErrMsg("Can't generate. Out of RAM!!",0);
  232.     return;
  233.   }
  234.  
  235.   if (Pict->Flags & NO_RAM_GENERATE ) {
  236.     DispErrMsg("Can't save counts. Out of RAM!!",0);
  237.   }
  238.  
  239.   /* calculate new picture's coordinates from zoom box */
  240.  
  241.   ZoomIn( Pict );
  242.   Pict->CurLine = 0;
  243.  
  244.   /* clear the picture area */
  245.  
  246.   if (!(Pict->Flags & LENS_DISPLAYED)) {
  247.  
  248.     SetAPen(  Pict->Window->RPort, NORMALPEN );
  249.     RectFill( Pict->Window->RPort, Pict->LeftMarg, Pict->TopMarg,
  250.               Pict->Window->Width - Pict->RightMarg - 1,
  251.               Pict->Window->Height - Pict->BotMarg - 1);
  252.   }
  253. }
  254.  
  255. GenTask() {
  256.  
  257.   register struct Picture *Pict;
  258.  
  259.   int MandelbrotInt32();
  260.   int MandelbrotInt32II();
  261.   int MandelbrotIEEE();
  262.   int MandelbrotFFP();
  263.  
  264.   int JuliaInt32();
  265.   int JuliaIEEE();
  266.   int JuliaFFP();
  267.  
  268.   LONG SPFieee();
  269.  
  270. #ifdef MULTI
  271.   geta4();
  272. #endif
  273.  
  274.   Pict = GenNPict;
  275.  
  276.   /* Signal Parent that we have accessed GenNPict */
  277.  
  278.   Signal( mTask, pSigMask );
  279.  
  280.   /* Lower our priority while we generate */
  281.  
  282.   SetTaskPri( FindTask(0), TaskPri );
  283.  
  284.   Pict->GenChildState = GENINCOMPLETE;
  285.  
  286.   if (GetTaskSig( Pict ) == UNSUCCESSFUL) {
  287.     Pict->GenChildState = NOSIGSTATE;
  288.  
  289.   } else {
  290.     Pict->GenChildState = GENINCOMPLETE;
  291.  
  292.     if ( Pict->pNode.ln_Type == MANDPICT ) {
  293.  
  294.       switch ( Pict->MathMode ) {
  295.         case 0:
  296.              MandelbrotInt32( Pict );
  297.              break;
  298.  
  299.         case 2:
  300.         case 4:
  301.              MandelbrotIEEE( Pict );
  302.              break;
  303.  
  304.         case 3:
  305.              MandelbrotInt32II( Pict );
  306.              break;
  307.  
  308.         case 1: {
  309.                /*
  310.                 * Constraints for IEEE to FFP conversion
  311.                 *
  312.                 *  1. SPFieee() expects 32 bit IEEE floats
  313.                 *  2. The C language always promotes floats to doubles for
  314.                 *     parameter passing.
  315.                 *  3. doubles are 64 bits wide
  316.                 *
  317.                 * Therefore I must do the following:
  318.                 *
  319.                 *  1. Convert double parameters to float
  320.                 *  2. Take the address of the floats and cast them to *ULONG
  321.                 *  3. Indirect off the ULONG pointers that are pointing to
  322.                 *     32 IEEE format floats (gross eh?) as parameters to FFP
  323.                 *     Mandelbrot function.
  324.                 */
  325.  
  326.              /* 32 bit IEEE float variables */
  327.  
  328.              float StartX_float, StartY_float, GapX_float, GapY_float;
  329.  
  330.              /* convert 64 bit IEEE variables into 32 bit IEEE variables */
  331.  
  332.              StartX_float = Pict->RealLow;
  333.              StartY_float = Pict->ImagLow + Pict->CurLine*Pict->RealGap;
  334.              GapX_float   = Pict->RealGap;
  335.              GapY_float   = Pict->ImagGap;
  336.  
  337.              /*
  338.               * calculate pointers and convert them to pointers to ULONG
  339.               * so that when we indirect off of these and pass the results
  340.               * as parameters they are not promoted to doubles.
  341.               */
  342.  
  343.  
  344.              MandelbrotFFP( Pict,
  345.                             *( (ULONG *) &StartX_float ),
  346.                             *( (ULONG *) &StartY_float ),
  347.                             *( (ULONG *) &GapX_float   ),
  348.                             *( (ULONG *) &GapY_float   ));
  349.              }
  350.              break;
  351.       }
  352.     } else {
  353.  
  354.       switch ( Pict->MathMode ) {
  355.  
  356.         case 0:
  357.         case 3:
  358.              JuliaInt32( Pict );
  359.              break;
  360.  
  361.         case 2:
  362.         case 4:
  363.              JuliaIEEE( Pict );
  364.              break;
  365.  
  366.         case 1: {
  367.              /*
  368.               * Constraints for IEEE to FFP conversion
  369.               *
  370.               *  1. SPFieee() expects 32 bit IEEE float
  371.               *  2. The C language always promotes floats to doubles for
  372.               *     parameter passing.
  373.               *  3. doubles are 64 bits wide
  374.               *
  375.               * Therefore I must do the following:
  376.               *
  377.               *  1. Convert double parameters to float
  378.               *  2. Take the address of the floats and cast them to *ULONG
  379.               *  3. Indirect off the ULONG pointers that are pointing to
  380.               *     32 IEEE format floats (gross eh?) as parameters to FFP
  381.               *     Julia function.
  382.               */
  383.  
  384.              /* 32 bit IEEE float variables */
  385.  
  386.              float JuliaX_float, JuliaY_float;
  387.              float StartX, StartY, GapX, GapY;
  388.  
  389.              /* convert 64 bit IEEE variables into 32 bit IEEE variables */
  390.  
  391.              JuliaX_float = Pict->Real;
  392.              JuliaY_float = Pict->Imag;
  393.              StartX = Pict->RealLow;
  394.              StartY = Pict->ImagLow;
  395.              GapX   = Pict->RealGap;
  396.              GapY   = Pict->ImagGap;
  397.  
  398.              /*
  399.               * calculate pointers and convert them to pointers to ULONG
  400.               * so that when we indirect off of these and pass the results
  401.               * as parameters they are not promoted to doubles.
  402.               */
  403.  
  404.              JuliaFFP( Pict, *( (ULONG *) &JuliaX_float ),
  405.                              *( (ULONG *) &JuliaY_float ),
  406.                              *( (ULONG *) &StartX ),
  407.                              *( (ULONG *) &StartY ),
  408.                              *( (ULONG *) &GapX ),
  409.                              *( (ULONG *) &GapY ) );
  410.              }
  411.              break;
  412.       }
  413.     }
  414.     Pict->GenChildState = GENCOMPLETE;
  415.   }
  416.  
  417. #ifdef MULTI
  418.  
  419.   /* Indicate that generation has finished for this task */
  420.  
  421.   Signal( mTask, mSigMask );               /* signal parent as to change */
  422.  
  423.   while (Pict->GenState != KILLSTATE) {    /* Wait for task to be removed */
  424.  
  425.     while (Pict->GenState == GENERATESTATE) {   /* spin 'till parent kills us */
  426.     }
  427.  
  428.     /* accept any pauses that the parent may send too late */
  429.  
  430.     if (Pict->GenState == PAUSESTATE) {
  431.       ChildSignal(Pict);  /* signal back so parent doesn't hang */
  432.     }
  433.   }
  434.  
  435.   /* We've been informed that we will die, so free up resources */
  436.  
  437.   FreeSignal( Pict->gSigBit );
  438.   Signal( mTask, pSigMask );               /* signal death O.K. */
  439.   Wait( 0L );                              /* stop here forever */
  440. #endif
  441. }
  442.  
  443. InitMand( Pict )
  444.   register struct Picture *Pict;
  445. {
  446.  
  447.   Pict->Real   = 0.0;
  448.   Pict->Imag   = 0.0;
  449. }
  450.  
  451. SetWindowActive( Window, Active )
  452.   register struct Window *Window;
  453.   char Active;
  454. {
  455.   struct Picture *Pict;
  456.  
  457.   if ( Window ) {
  458.  
  459.     Pict = (struct Picture *) Window->UserData;
  460.  
  461.     if ( ! (Pict->Flags & BORDERLESS_PROJ)) {
  462.       Window->Title[0] = Active;
  463.       SetWindowTitles( Window, Window->Title, -1 );
  464.     }
  465.   }
  466. }
  467.  
  468. /*
  469.  * Free up old memory and get memory for new picture
  470.  */
  471. GetCountsMemory( Pict )
  472.   register struct Picture *Pict;
  473. {
  474.   /* free up old pictures iteration count pile */
  475.  
  476.   FreeCounts( Pict );
  477.  
  478.   /* Allocate memory for new picture */
  479.  
  480.   Pict->CountsSize = Pict->CountX * Pict->CountY * sizeof(SHORT);
  481.   Pict->Counts     = (SHORT *) safeAllocMem(Pict->CountsSize, MEMF_CLEAR );
  482.  
  483.   if (Pict->Counts == NULL) {
  484.  
  485.     Pict->CountsSize = Pict->CountX * sizeof(SHORT);
  486.     Pict->Counts     = (SHORT *) safeAllocMem(Pict->CountsSize, MEMF_CLEAR);
  487.  
  488.     if (Pict->Counts != NULL)
  489.       Pict->Flags     |= NO_RAM_GENERATE;
  490.  
  491.   } else {
  492.  
  493.     Pict->Flags     &= ~NO_RAM_GENERATE;
  494.   }
  495. }
  496.  
  497. FreeCounts( Pict )
  498.   register struct Picture *Pict;
  499. {
  500.   if ( Pict->Counts ) {
  501.  
  502.     FreeMem( Pict->Counts, Pict->CountsSize );
  503.     Pict->Counts = NULL;
  504.   }
  505. }
  506.  
  507. struct Gadget *
  508. MakePictGads( Type )
  509.   register int Type;
  510. {
  511.   register struct Gadget    *gadget;
  512.   register struct Gadget *Newgadget;
  513.   register struct Gadget *Firstgadget;
  514.   register struct IntuiText  *Intui;
  515.   register char *str;
  516.  
  517.   struct Border *Border, *MakeShadow();
  518.  
  519.   register int i,j,k;
  520.  
  521.   struct IntuiText *ShadowIntui();
  522.  
  523.   j = TOPMARG;
  524.  
  525.   if ( Type == MANDPICT ) {
  526.     k = 4;
  527.   } else {
  528.     k = 5;
  529.   }
  530.  
  531.   Firstgadget = NULL;
  532.  
  533.   for (i = 0; i < k; i++) {
  534.  
  535.     Newgadget = MakeBool(-15,j, 12,12, 0,(PICTTYPE<<WINDTYPEBITS)+i,NULL);
  536.  
  537.     if (Newgadget) {
  538.  
  539.       if ( i == 0 ) {
  540.  
  541.         Firstgadget = Newgadget;
  542.  
  543.       } else {
  544.  
  545.         gadget->NextGadget = Newgadget;
  546.       }
  547.  
  548.       Newgadget->Flags      |= GRELRIGHT;
  549.       Newgadget->Activation |= RIGHTBORDER;
  550.  
  551.       gadget = Newgadget;
  552.  
  553.       j += 14;
  554.  
  555.       switch( i ) {
  556.         case  0:  str = "C"; break;
  557.         case  1:  str = "G"; break;
  558.         case  2:  str = "I"; break;
  559.         case  3:  str = "O"; break;
  560.         case  4:  str = "J"; break;
  561.       }
  562.  
  563.       Intui = ShadowIntui( str, 3, 3);
  564.  
  565.       if (Intui == NULL) {
  566.         FreeGadgets( Firstgadget );
  567.       }
  568.  
  569.       gadget->GadgetText = Intui;
  570.  
  571. #define NUMPATCHCORNERS 5
  572.  
  573.       Border = MakeShadow( NORMALPEN, NUMPATCHCORNERS );
  574.  
  575.       if ( Border ) {
  576.         InitPatch( Border );
  577.         Border->NextBorder = (struct Border *) gadget->GadgetRender;
  578.         gadget->GadgetRender = (APTR) Border;
  579.       }
  580.  
  581.     } else {
  582.  
  583.       if (Firstgadget)
  584.         FreeGadgets( Firstgadget );
  585.  
  586.       return( NULL );
  587.     }
  588.   }
  589.   return( Firstgadget );
  590. }
  591.  
  592. SetGenGad( Pict )
  593.   register struct Picture *Pict;
  594. {
  595.   register struct Window *Window;
  596.   register struct Gadget *Gadget;
  597.   register struct IntuiText *Intui;
  598.   register char c;
  599.   register int  place;
  600.  
  601.   if (Pict == NULL)
  602.     return;
  603.  
  604.   if (Pict->Flags & BORDERLESS_PROJ)
  605.     return;
  606.  
  607.   Window = Pict->Window;
  608.  
  609.   if (Window) {
  610.  
  611.     if ( Pict->gTask )
  612.       c = 'S';
  613.     else
  614.       c = 'G';
  615.  
  616.     Gadget = Pict->Gadgets->NextGadget;
  617.  
  618.     place = RemoveGadget( Window, Gadget );
  619.  
  620.     Intui = Gadget->GadgetText;
  621.  
  622.     Intui = Intui->NextText;
  623.     Intui->IText[0] = c;
  624.  
  625.     Intui = Intui->NextText;
  626.     Intui->IText[0] = c;
  627.  
  628.     AddGadget( Window, Gadget, place );
  629.  
  630.     RefreshGadgets( Pict->Gadgets, Window, NULL );
  631.   }
  632. }
  633.  
  634. InitPatch( Border )
  635.   register struct Border *Border;
  636. {
  637.   register SHORT *NewCounts;
  638.  
  639.   NewCounts = Border->XY;
  640.  
  641.   *NewCounts++ = 3;       *NewCounts++ = 11;
  642.   *NewCounts++ = 2;       *NewCounts++ = 11;
  643.   *NewCounts++ = 2;       *NewCounts++ = 2;
  644.   *NewCounts++ = 11;      *NewCounts++ = 2;
  645.   *NewCounts++ = 11;      *NewCounts++ = 3;
  646.  
  647. } /* InitPatch */
  648.  
  649. /*
  650.  * Open the Picture window
  651.  */
  652. OpenPicture( Pict )
  653.   struct Picture    *Pict;
  654. {
  655.   extern struct Window *OpenMyWind();
  656.  
  657.   register struct Window    *Window;
  658.   register struct NewWindow *NewWind;
  659.  
  660.   register LONG width, height;
  661.   register LONG extrax,extray;
  662.  
  663.   struct Gadget *gadgets, *MakePictGads();
  664.  
  665.   if ( Pict->Window == NULL ) {
  666.  
  667.     width  = Pict->CountX;
  668.     height = Pict->CountY;
  669.  
  670.     NewWind = Pict->NewWind;
  671.  
  672.     if (Pict->Flags & BORDERLESS_PROJ) {
  673.  
  674.       NewWind->Flags = ACTIVATE | REPORTMOUSE | NOCAREREFRESH |
  675.                        SMART_REFRESH | BORDERLESS;
  676.       NewWind->Title = NULL;
  677.       Pict->Gadgets  = gadgets = NULL;
  678.  
  679.       if (Pict->LeftEdge+Pict->CountX+LEFTMARG+RIGHTMARG == screen->Width &&
  680.           Pict->TopEdge +Pict->CountY+TOPMARG+BOTMARG    == screen->Height) {
  681.  
  682.         Pict->LeftMarg  = LEFTMARG;
  683.         Pict->RightMarg = RIGHTMARG;
  684.         Pict->TopMarg   = TOPMARG;
  685.         Pict->BotMarg   = BOTMARG;
  686.       } else {
  687.  
  688.         Pict->LeftMarg  = 0;
  689.         Pict->RightMarg = 0;
  690.         Pict->TopMarg   = 0;
  691.         Pict->BotMarg   = 0;
  692.       }
  693.     } else {
  694.  
  695.       NewWind->Flags = WINDOWCLOSE | WINDOWDEPTH | WINDOWSIZING |
  696.                        WINDOWDRAG | ACTIVATE | REPORTMOUSE | NOCAREREFRESH |
  697.                        SMART_REFRESH;
  698.       NewWind->Title = (UBYTE *) Pict->Title;
  699.       Pict->Gadgets  = gadgets = MakePictGads( Pict->pNode.ln_Type );
  700.  
  701.       Pict->LeftMarg  = LEFTMARG;
  702.       Pict->RightMarg = RIGHTMARG;
  703.       Pict->TopMarg   = TOPMARG;
  704.       Pict->BotMarg   = BOTMARG;
  705.     }
  706.  
  707.     width  += Pict->LeftMarg + Pict->RightMarg;
  708.     height += Pict->TopMarg  + Pict->BotMarg;
  709.  
  710.     extrax = width - screen->Width;
  711.     extray = height - screen->Height;
  712.  
  713.     if ( extrax > 0 || extray > 0 ) {
  714.  
  715.       ThrowTask(  Pict);
  716.       FreeCounts( Pict);
  717.       DispErrMsg("Picture too big. Regenerate",0);
  718.  
  719.       if ( extrax > 0 ) {
  720.         Pict->CountX -= extrax;
  721.         width -= extrax;
  722.       }
  723.  
  724.       if ( extray > 0 ) {
  725.         Pict->CountY -= extray;
  726.         height -= extray;
  727.       }
  728.     }
  729.  
  730.     NewWind->LeftEdge = Pict->LeftEdge;
  731.     NewWind->TopEdge  = Pict->TopEdge;
  732.  
  733.     Window = OpenMyWind(NewWind, screen, gadgets, width, height );
  734.  
  735.     Pict->Window  = Window;
  736.  
  737.     if (Window == NULL) {
  738.  
  739.       DispErrMsg("Can't open picture window",0);
  740.       FreeGadgets( Pict->Gadgets );
  741.       ThrowPict(Pict);
  742.       return( -1 );
  743.  
  744.     } else {
  745.  
  746.       CurWind = Window;
  747.       DisplayMsg();
  748.  
  749.       SetAPen(  Window->RPort, NORMALPEN );
  750.  
  751.       if (Pict->Flags & BORDERLESS_PROJ) {
  752.         RectFill( Window->RPort, Pict->LeftMarg, Pict->TopMarg,
  753.                   NewWind->Width-Pict->RightMarg-1,
  754.                   NewWind->Height-Pict->BotMarg-1);
  755.       } else {
  756.         RectFill( Window->RPort, Pict->LeftMarg, Pict->TopMarg,
  757.                   NewWind->Width, NewWind->Height);
  758.       }
  759.  
  760.       Window->UserData = (BYTE *) Pict;
  761.  
  762.       MoveResize( Pict->Window, &Pict->SizingGadget );
  763.       BorderWindow( Window );
  764.  
  765.       if (Pict->CycleOn) {
  766.         CreateCycle();
  767.       }
  768.     }
  769.   }
  770.   SetGenGad( Pict );
  771.   return( 0 );
  772. } /* OpenPicture */
  773.  
  774. MoveResize( Window, RetGadget )
  775.   register struct Window *Window;
  776.   register struct Gadget **RetGadget;
  777. {
  778.   register struct Gadget *Gadget;
  779.   register int place;
  780.  
  781.   Gadget = Window->FirstGadget;
  782.  
  783.   while ( Gadget && !(Gadget->GadgetType & SIZING)) {
  784.     Gadget = Gadget->NextGadget;
  785.   }
  786.  
  787.   if (Gadget) {
  788.  
  789.     *RetGadget = Gadget;
  790.  
  791.     place = RemoveGadget( Window, Gadget );
  792.  
  793.     if (XScale == 0)
  794.       Gadget->LeftEdge -= 2;
  795.  
  796.     if (YScale == 0)
  797.       Gadget->TopEdge  -= 3;
  798.     else
  799.       Gadget->TopEdge  -= 1;
  800.  
  801.     AddGadget( Window, Gadget, place );
  802.  
  803.     RefreshGList( Gadget, Window, NULL, 1);
  804.   }
  805. }
  806.  
  807. /*
  808.  * Close the Mandelbrot Window
  809.  */
  810. ClosePicture( Pict )
  811.   register struct Picture   *Pict;
  812. {
  813.   register struct Window    *Window;
  814.   register struct NewWindow *NewWindow;
  815.  
  816.   if ( (Window = Pict->Window) != NULL) {
  817.  
  818.     KillCycle();
  819.     FreeScrollTemp(Pict);
  820.  
  821.     Pict->LeftEdge = Window->LeftEdge;
  822.     Pict->TopEdge = Window->TopEdge;
  823.  
  824.     CloseMyWind(Window, Pict->Gadgets );
  825.  
  826.     Pict->Window = NULL;
  827.     Pict->Gadgets = NULL;
  828.     Pict->Flags &= ~LENS_DISPLAYED;
  829.   }
  830. }
  831.